package org.gc.service.security;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.persistence.EntityExistsException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.gc.common.entity.security.User;
import org.gc.common.vo.security.UserVO;
import org.gc.dao.security.UserDao;
import org.gc.exception.UserExistsException;
import org.gc.service.base.BaseServiceImpl;
import org.gc.util.MailEngine;
import org.gc.webapp.util.RequestUtil;
import org.gc.webapp.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.providers.encoding.PasswordEncoder;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;


@Service
public class UserServiceImpl extends BaseServiceImpl<User, UserVO, Long> implements UserService {
    /**
     * Logger for this class
     */
    private static final Log logger = LogFactory.getLog(UserServiceImpl.class);

    private UserDao userDao;
    private MailEngine mailEngine;
    
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Autowired
    public void setMailEngine(MailEngine mailEngine) {
        this.mailEngine = mailEngine;
    }

    @Autowired
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @PostConstruct
    public void afterConstruct(){
        super.setBaseDao(userDao);
        super.setEntityClass(User.class);
        super.setEntityVOClass(UserVO.class);
    }
    
    
    public UserVO getUserByUsername(String username) throws UsernameNotFoundException {
        return super.getBy("username", username);
    }
    public UserVO register(UserVO userVO) throws UserExistsException{
        UserVO result = null;
        userVO.setPassword(passwordEncoder.encodePassword(userVO.getPassword(), null));
        try {
            result = save(userVO);
        } catch (DataIntegrityViolationException e) {
            logger.warn(e.getMessage());
            throw new UserExistsException("User '" + userVO.getUsername() + "' already exists!");
        } catch (EntityExistsException e) { // needed for JPA
            logger.warn(e.getMessage());
            throw new UserExistsException("User '" + userVO.getUsername() + "' already exists!");
        }
        //sendRegisterSuccessEmail(userVO);
        return result;
    }
    /**
     * 发送注册成功邮件
     * @param userVO
     */
    private void sendRegisterSuccessEmail(UserVO userVO){
        MimeMessage msg = mailEngine.getMailSender().createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(msg);
        
        try {
            messageHelper.setTo(userVO.getEmail());
            messageHelper.setSubject("Group注册成功");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("username", userVO.getUsername());
        model.put("name", userVO.getName());
        HttpServletRequest request = ServletActionContext.getRequest();
        model.put("indexUrl", RequestUtil.getAppURL(request));
        mailEngine.sendMessage(msg, "mailTemplate/registerSuccess.vm", model);
        
    }
    /**
     * Send mail to reset password
     * @param userVO
     */    
    private void sendResetPasswordEMail(UserVO userVO)
    {
        MimeMessage msg = mailEngine.getMailSender().createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(msg);
        String newpassword = StringUtil.randomString(8);
        try {
            messageHelper.setTo(userVO.getEmail());
            messageHelper.setSubject("Group密码重置");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("username", userVO.getUsername());
        model.put("name", userVO.getName());
        model.put("password", newpassword);
        mailEngine.sendMessage(msg, "mailTemplate/resetPassword.vm", model);
        userVO.setPassword(passwordEncoder.encodePassword(newpassword,null));
        save(userVO);
    }
    /**
     * update password
     * @param userVO
     */     
    public boolean updatePassword(UserVO userVO, String oldPassword, String newPassword)
    {
    	boolean result;
    	String encodedPassword = passwordEncoder.encodePassword(oldPassword, null);
    	if(userVO.getPassword().equals(encodedPassword)){
    		userVO.setPassword(passwordEncoder.encodePassword(newPassword, null));
    		save(userVO);
    		result = true;
    	}
    	else{
    		result = false;
    	}
    	return result;
    }
    /**
     * reset password
     * @param userVO
     */      
    public boolean resetPassword(String username, String email)
    {
    	boolean result = false;
    	UserVO userVO = getUserByUsername(username);
    	if(userVO == null || !userVO.getEmail().equals(email.trim()))
    	{
    		result = false;
    	}
    	else
    	{
    		sendResetPasswordEMail(userVO);
    		result = true;
    	}
    	return result;
    }
	@Override
	public List<UserVO> getAllAdminUser() {
		List<UserVO> result = new ArrayList<UserVO>();
        result = (List<UserVO>)dozerBeanUtil.convertList(userDao.getAllAdminUser(),UserVO.class);
        return result;
	}
	@Override
	public List<UserVO> getAllNonAdminUser() {
		List<UserVO> result = new ArrayList<UserVO>();
        result = (List<UserVO>)dozerBeanUtil.convertList(userDao.getAllNonAdminUser(),UserVO.class);
        return result;
	}
	@Override
	public String xpassword(Long userid) {
		UserVO user = get(userid);
		String newpassword = StringUtil.randomString(6);
		user.setPassword(passwordEncoder.encodePassword(newpassword,null));
        save(user);
		return newpassword;
	}
}
